package com.ext.aic.handler;

import android.content.Context;
import android.net.Uri;

import androidx.lifecycle.LifecycleOwner;

import com.ext.aic.apis.attachment.AttachmentConfirmRequest;
import com.ext.aic.apis.attachment.AttachmentUrlRequest;
import com.ext.aic.apis.attachment.ObsUploadRequest;
import com.ext.aic.apis.attachment.PreUploadRequest;
import com.ext.aic.beans.PreUploadInfo;
import com.ext.aic.beans.params.AttachmentConfirmParams;
import com.ext.aic.beans.response.AttachmentConfirmResponse;
import com.ext.aic.beans.response.AttachmentUrlResponse;
import com.ext.aic.beans.response.PreUploadResponse;
import com.ext.aic.events.AttachmentUploadCallback;
import com.eyinfo.android_pure_utils.HandlerManager;
import com.eyinfo.android_pure_utils.events.Action0;
import com.eyinfo.android_pure_utils.events.RunnableParamsN;
import com.eyinfo.storage.files.FileUtils;

import java.io.File;

import lombok.Setter;

//附件上传管理类
public class AttachmentHandler<P> {

    private Context context;
    private LifecycleOwner lifecycleOwner;
    private File file;
    private P value;

    @Setter
    private AttachmentUploadCallback<P> uploadCallback;

    private Action0 completeCallback;

    public AttachmentHandler(Action0 callback) {
        this.completeCallback = callback;
    }

    public void upload(Context context, LifecycleOwner lifecycleOwner, String resourceName, File file, P value) {
        this.context = context;
        this.lifecycleOwner = lifecycleOwner;
        this.file = file;
        this.value = value;
        uploadCallback.onAttachmentStart(value);
        PreUploadHandler preUploadHandler = new PreUploadHandler();
        preUploadHandler.request(resourceName);
    }

    private class PreUploadHandler extends PreUploadRequest {
        @Override
        protected void onPreUploadSuccess(PreUploadResponse response) {
            PreUploadInfo uploadInfo = new PreUploadInfo();
            uploadInfo.setHeaders(response.getHeaders());
            analyzePreUploadAddress(uploadInfo, response.getUploadUrl());
            ObsUploadHandler obsUploadHandler = new ObsUploadHandler();
            obsUploadHandler.upload(context, uploadInfo, file);
        }

        private void analyzePreUploadAddress(PreUploadInfo uploadInfo, String uploadUrl) {
            Uri uri = Uri.parse(uploadUrl);
            String accessKeyId = uri.getQueryParameter("AccessKeyId");
            String expires = uri.getQueryParameter("Expires");
            String signature = uri.getQueryParameter("Signature");
            uploadInfo.setAccessKeyId(accessKeyId);
            uploadInfo.setExpires(expires);
            uploadInfo.setSignature(signature);
            int index = uploadUrl.indexOf("?");
            if (index != -1) {
                String pureUrl = uploadUrl.substring(0, index);
                uploadInfo.setUrl(pureUrl);
                uploadInfo.setFileName(FileUtils.getName(pureUrl));
            }
            uploadInfo.setOriginalUrl(uploadUrl);
        }

        @Override
        protected void onPreUploadFailed(String resourceName) {
            System.out.println("[Attachment]预上传失败,资源名称=" + resourceName);
            HandlerManager.getInstance().post(new RunnableParamsN<Object>() {
                @Override
                public void run(Object... objects) {
                    uploadCallback.onAttachmentFailure(value);
                    uploadCallback.onAttachmentEnd(value);
                    if (completeCallback != null) {
                        completeCallback.call();
                    }
                }
            });
        }
    }

    private class ObsUploadHandler extends ObsUploadRequest {

        private int currentProgress = 0;

        @Override
        protected void onUploadProgress(PreUploadInfo uploadInfo, int percent) {
            if ((percent - currentProgress) > 3 || percent == 100) {
                currentProgress = percent;
                HandlerManager.getInstance().post(new RunnableParamsN<Object>() {
                    @Override
                    public void run(Object... objects) {
                        uploadCallback.onAttachmentProgress(value, percent);
                    }
                });
            }
        }

        @Override
        protected void onUploadFailure(PreUploadInfo uploadInfo, String message) {
            System.out.println("[Attachment]上传附件失败,上传地址=" + uploadInfo.getOriginalUrl());
            HandlerManager.getInstance().post(new RunnableParamsN<Object>() {
                @Override
                public void run(Object... objects) {
                    uploadCallback.onAttachmentFailure(value);
                    uploadCallback.onAttachmentEnd(value);
                    if (completeCallback != null) {
                        completeCallback.call();
                    }
                }
            });
        }

        @Override
        protected void onUploadSuccess(PreUploadInfo uploadInfo) {
            AttachmentConfirmParams attachmentConfirmParams = new AttachmentConfirmParams();
            attachmentConfirmParams.setFilename(uploadInfo.getFileName());
            attachmentConfirmParams.setFileUrl(uploadInfo.getUrl());
            AttachmentConfirmHandler confirmHandler = new AttachmentConfirmHandler();
            confirmHandler.request(context, lifecycleOwner, attachmentConfirmParams);
        }
    }

    private class AttachmentConfirmHandler extends AttachmentConfirmRequest {
        @Override
        protected void onAttachmentConfirmResponseFail(Throwable throwable, AttachmentConfirmParams params) {
            System.out.println("[Attachment]确认附件失败,文件地址=" + params.getFileUrl());
            HandlerManager.getInstance().post(new RunnableParamsN<Object>() {
                @Override
                public void run(Object... objects) {
                    uploadCallback.onAttachmentFailure(value);
                    uploadCallback.onAttachmentEnd(value);
                    if (completeCallback != null) {
                        completeCallback.call();
                    }
                }
            });
        }

        @Override
        protected void onAttachmentConfirmResponseSuccess(AttachmentConfirmResponse response) {
            AttachmentUrlHandler attachmentUrlHandler = new AttachmentUrlHandler();
            attachmentUrlHandler.request(context, lifecycleOwner, response.getId(), response.getFilename());
        }
    }

    private class AttachmentUrlHandler extends AttachmentUrlRequest {
        @Override
        protected void onAttachmentUrlFail(Throwable throwable, String attachmentId, String resourceName) {
            System.out.println("[Attachment]获取连接失败,资源名称=" + resourceName + ",ID=" + attachmentId);
            HandlerManager.getInstance().post(new RunnableParamsN<Object>() {
                @Override
                public void run(Object... objects) {
                    uploadCallback.onAttachmentFailure(value);
                    uploadCallback.onAttachmentEnd(value);
                    if (completeCallback != null) {
                        completeCallback.call();
                    }
                }
            });
        }

        @Override
        protected void onAttachmentUrlSuccess(AttachmentUrlResponse response, String resourceName, String attachmentId) {
            System.out.println("[Attachment]获取连接成功,资源名称=" + resourceName + ",ID=" + attachmentId + ",url=" + response.getDownloadUrl());
            HandlerManager.getInstance().post(new RunnableParamsN<Object>() {
                @Override
                public void run(Object... objects) {
                    uploadCallback.onAttachmentSuccess(value, resourceName, response.getDownloadUrl(), file.getAbsolutePath(), attachmentId);
                    uploadCallback.onAttachmentEnd(value);
                    if (completeCallback != null) {
                        completeCallback.call();
                    }
                }
            });
        }
    }
}
